package com.yingxin.yxerp.module.organization.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.dto.AttachmentDto;
import com.yingxin.yx.framework.commons.dto.PageOut;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.commons.helper.ListHelper;
import com.yingxin.yx.framework.mybatisplus.PageHelper;
import com.yingxin.yx.framework.tool.string.MyStringTool;
import com.yingxin.yx.framework.user.core.IUserSupport;
import com.yingxin.yx.framework.user.dto.AppPermissionDto;
import com.yingxin.yx.framework.user.dto.PermissionDto;
import com.yingxin.yx.framework.user.dto.UserDto;
import com.yingxin.yxerp.module.attachment.constant.AttachConst;
import com.yingxin.yxerp.module.attachment.entity.Attachment;
import com.yingxin.yxerp.module.attachment.service.IAttachmentService;
import com.yingxin.yxerp.module.common.util.SmBeanUtils;
import com.yingxin.yxerp.module.easypoi.excel.ExcelExportUtil;
import com.yingxin.yxerp.module.easypoi.excel.entity.ExportParams;
import com.yingxin.yxerp.module.organization.entity.User;
import com.yingxin.yxerp.module.organization.entity.enums.StaffStatus;
import com.yingxin.yxerp.module.organization.helper.SeniorityHelper;
import com.yingxin.yxerp.module.organization.mapper.UserAppRoleMapper;
import com.yingxin.yxerp.module.organization.mapper.UserMapper;
import com.yingxin.yxerp.module.organization.mapper.UserRoleMapper;
import com.yingxin.yxerp.module.organization.service.IDepartmentService;
import com.yingxin.yxerp.module.organization.service.IUserService;
import com.yingxin.yxerp.module.organization.vo.export.UserExportVo;
import com.yingxin.yxerp.module.organization.vo.req.*;
import com.yingxin.yxerp.module.organization.vo.resp.*;
import com.yingxin.yxerp.module.permission.mapper.RoleMapper;
import com.yingxin.yxerp.module.permission.vo.req.RoleQueryVo;
import com.yingxin.yxerp.module.permission.vo.req.helper.UserAppPermissionTreeHelper;
import com.yingxin.yxerp.module.permission.vo.req.helper.UserPermissionTreeHelper;
import com.yingxin.yxerp.module.permission.vo.resp.RoleRespVo;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 用户 前端控制器
 * @author fanchao
 * @since 2021-05-13
 */

@ApiSort(10)
@RestController
@RequestMapping("/organization/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    @SuppressWarnings("all")
    private UserMapper userMapper;

    @Autowired
    @SuppressWarnings("all")
    private RoleMapper roleMapper;

    @Autowired
    @SuppressWarnings("all")
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserAppRoleMapper userAppRoleMapper;

    @Autowired
    private IAttachmentService attachmentService;

    @Autowired
    private IUserSupport userSupport;

    @ApiOperation(value = "查询列表（分页）")
    @PostMapping("/page")
    public PageOut<UserRespVo> page(@RequestBody UserQueryVo queryVo) {
        IPage<UserRespVo> page = userMapper.pageVo(PageHelper.in(queryVo), queryVo);
        return PageHelper.out(page);
    }

    @ApiOperation(value = "查询列表（全部）")
    @PostMapping("/list")
    public List<UserRespVo> list(@RequestBody(required = false) UserQueryVo queryVo) {
        if (queryVo == null) {
            queryVo = new UserQueryVo();
        }
        return userMapper.listVo(queryVo);
    }

    @ApiOperation(value = "获取所有锁定的用户")
    @PostMapping("/list/lock")
    public List<UserRespVo> listLock( @RequestBody(required = false) UserQueryVo queryVo ){
        queryVo.setLockFlag( CommonConst.TRUE );
        List<String> staffStatusList = new ArrayList<>();
        staffStatusList.add( StaffStatus.SY );
        staffStatusList.add( StaffStatus.ZZ );
        queryVo.setStaffStatusList( staffStatusList );
        List<UserRespVo> userList = userMapper.listVo( queryVo );
        return userList;
    }

    @ApiOperation(value = "查询列表（全部）")
    @PostMapping("/list/code")
    public List<UserCodeRespVo> listCode() {
        return userMapper.listCode();
    }

    @ApiOperation(value = "查询列表（可用用户）")
    @PostMapping("/page/enable")
    public PageOut<UserRespVo> pageEnable(@RequestBody(required = false) UserQueryVo queryVo) {
        if (queryVo == null) {
            queryVo = new UserQueryVo();
        }
        List<String> staffStatusList = new ArrayList<>();
        staffStatusList.add(StaffStatus.SY);
        staffStatusList.add(StaffStatus.ZZ);
        queryVo.setStaffStatusList(staffStatusList);
        return page(queryVo);
    }

    @ApiOperation(value = "查询列表（可用用户）")
    @PostMapping("/list/enable")
    public List<UserRespVo> listEnable(@RequestBody(required = false) UserQueryVo queryVo) {
        if (queryVo == null) {
            queryVo = new UserQueryVo();
        }
        List<String> staffStatusList = new ArrayList<>();
        staffStatusList.add(StaffStatus.SY);
        staffStatusList.add(StaffStatus.ZZ);
        queryVo.setStaffStatusList(staffStatusList);
        return list(queryVo);
    }

    @ApiOperation(value = "根据id查询")
    @GetMapping("/{id}")
    public UserRespVo get(@PathVariable("id") String id) {
        UserRespVo user = userMapper.getVo( id );
        if( StringUtils.isNotBlank( user.getDeptIds() ) ) {
            user.setBelongToAllDeptName(
                    departmentService.getByDeptIds( MyStringTool.split( user.getDeptIds(), "," ) ) );
        }
        List<UserRolesRespVo> userRolesList = userRoleMapper.listVo(new UserRolesQueryVo(id));
        List<UserRolesRespVo> userAppRolesList = userAppRoleMapper.listVo(new UserRolesQueryVo(id));
        user.setRoles(userRolesList);
        user.setAppRoles(userAppRolesList);
        // 头像附件
        user.setAvatarAttachment(attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.AVATAR));
        // 员工照片
        user.setPhotograph(
                removeUselessPath( attachmentService.getByBiz( user.getId(), BusinessType.USER_PHOTO, null ) ) );
        // 身份证正面
        user.setIdCardFrontAttachment(
                removeUselessPath( attachmentService.getByBiz(user.getId(), BusinessType.USER_ID_PORTRAIT, null) ) );
        // 身份证反面
        user.setIdCardBackAttachment(
                removeUselessPath( attachmentService.getByBiz(user.getId(), BusinessType.USER_ID_NATIONAL_EMBLEM, null ) ) );
        // 学历附件
        // user.setEducationAttachmentList(attachmentService.listByBiz(user.getId(), BusinessType.USER, AttachConst.EDU));
        return user;
    }

    private AttachmentDto removeUselessPath( AttachmentDto dto ){
        if( ObjectUtil.isEmpty( dto ) ){
            return dto;
        }
        if( StringUtils.isBlank( dto.getAttachmentPath() ) ){
            return dto;
        }
        dto.setAttachmentPath( dto.getAttachmentPath().replace( "D://yx-files", "" ) );
        return dto;
    }


    @ApiOperation("用户菜单权限列表")
    @GetMapping("/permissions/{id}")
    public List<PermissionDto> listPermissions(@PathVariable("id") String id) {
        List<PermissionDto> permissions = userService.listPermissionDtoByUserId(id);
        return UserPermissionTreeHelper.build(permissions);
    }

    @ApiOperation("app用户菜单权限列表")
    @GetMapping("/permissions/app-android/{id}")
    public List<AppPermissionDto> listAppPermissions(@PathVariable("id") String id) {
        List<AppPermissionDto> permissions = userService.listAppPermissionDtoByUserId(id);
        return UserAppPermissionTreeHelper.buildMenu(permissions);
    }

    @ApiOperation("材质权限列表")
    @GetMapping("/permissions/material/{material}")
    public Boolean listMaterialPermissions(@PathVariable("material") String material) {
        UserDto user = userSupport.getUser();
        List<PermissionDto> permissions = userService.listPermissionDtoByUserId(user.getUserId());
        boolean status = false;
        for (PermissionDto permission : permissions) {
            if (material.equals(permission.getPermissionString())){
                status = true;
                break;
            }
        }
        return status;
    }

    @ApiOperation(value = "可用工号")
    @GetMapping("/maxStaffNo")
    public Integer getMaxStaffNo() {
        return userService.getMaxStaffNo() + 1;
    }

    @PreAuthorize("hasAuthority('sys:user:create')")
    @ApiOperation(value = "新增")
    @PostMapping
    public String create(@RequestBody @Valid UserCreateVo createVo) {
        User user = new User();
        BeanUtil.copyProperties(createVo, user);
        userService.create(user);
        return user.getId();
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @ApiOperation(value = "修改")
    @PutMapping
    public String update(@RequestBody @Valid UserUpdateVo updateVo) {
        User user = new User();
        BeanUtil.copyProperties(updateVo, user);
        userService.update(user);
        return user.getId();
    }

    @PreAuthorize("hasAuthority('sys:user:delete')")
    @ApiOperation(value = "删除")
    @DeleteMapping("/{id}")
    public void delete(@PathVariable("id") String id) {
        User user = userService.getById(id);
        userService.delete(user);
    }

    @PreAuthorize("hasAuthority('sys:user:enable')")
    @ApiOperation("启用")
    @PostMapping("/enable/{id}")
    public void enable(@PathVariable("id") String id) {
        User user = userService.getById(id);
        userService.enable(user);
    }

    @PreAuthorize("hasAuthority('sys:user:disable')")
    @ApiOperation("禁用")
    @PostMapping("/disable/{id}")
    public void disable(@PathVariable("id") String id) {
        User user = userService.getById(id);
        userService.disable(user);
    }

    @PreAuthorize("hasAuthority('sys:user:unlock')")
    @ApiOperation("解锁")
    @PostMapping("/unlock/{id}")
    public void unlock(@PathVariable("id") String id) {
        User user = userService.getById(id);
        userService.unlock(user);
    }

    @PreAuthorize("hasAuthority('sys:user:addRoles')")
    @ApiOperation(value = "用户角色选择列表")
    @GetMapping("/roles-select/{userId}")
    public List<RoleRespVo> getRoles(@PathVariable("userId") String userId) {
        List<RoleRespVo> roles = roleMapper.listVo(new RoleQueryVo());
        List<UserRolesRespVo> userRolesList = userRoleMapper.listVo(new UserRolesQueryVo(userId));
        Map<String, UserRolesRespVo> userRolesMap = ListHelper.toMap(UserRolesRespVo::getRoleId, userRolesList);
        for (RoleRespVo role : roles) {
            if (userRolesMap.containsKey(role.getId())) {
                role.setUserAdded(CommonConst.TRUE);
            } else {
                role.setUserAdded(CommonConst.FALSE);
            }
        }
        return roles;
    }

    @PreAuthorize("hasAuthority('sys:user:addRoles')")
    @ApiOperation(value = "角色设置")
    @PostMapping("/roles")
    public String addRoles(@RequestBody @Valid UserRolesUpdateVo reqVo) {
        userService.addRoles(reqVo.getUserId(), reqVo.getRoleIds());
        return reqVo.getUserId();
    }

    @ApiOperation(value = "app角色设置")
    @PostMapping("/app/roles")
    public String addAppRoles(@RequestBody @Valid UserRolesUpdateVo reqVo) {
        userService.addAppRoles(reqVo.getUserId(), reqVo.getRoleIds());
        return reqVo.getUserId();
    }

    @PreAuthorize("hasAuthority('sys:user:export')")
    @ApiOperation(value = "用户-导出")
    @PostMapping("/list-export")
    public String listExport(@RequestBody(required = false) UserQueryVo queryVo) {
        if (queryVo == null) {
            queryVo = new UserQueryVo();
        }
        List<UserRespVo> list = userMapper.listVo(queryVo);
        List<UserExportVo> exportList = SmBeanUtils.copyProperties(list, UserExportVo.class);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), UserExportVo.class, exportList);
        String fileName = ExcelExportUtil.out(workbook, "用户.xlsx");
        return fileName;
    }

    @ApiOperation(value = "登录人信息")
    @GetMapping("/loginUserInfo")
    public UserRespVo getLoginUser() {
        String userId = userSupport.getUserId();
        UserRespVo user = userMapper.getVo(userId);
        if (StringUtils.isNotEmpty(user.getDeptId())){
            List<DepartmentRespVo> deptList = departmentService.listParentById(user.getDeptId());
            user.setDeptNames(SeniorityHelper.getDeptNames(deptList));
        }
        user.setAvatarAttachment(attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.AVATAR));
        user.setSignAttachment(attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.SIGN));
        user.setIdCardFrontAttachment(attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.IDA));
        user.setIdCardBackAttachment(attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.IDB));
        user.setEducationAttachmentList(attachmentService.listByBiz(user.getId(), BusinessType.USER, AttachConst.EDU));
        return user;
    }

    @ApiOperation(value = "当前用户上传头像")
    @PostMapping("/avatar/upload")
    public AttachmentDto uploadAvatar(@RequestParam("file") MultipartFile file) {
        String userId = userSupport.getUserId();
        Attachment attachment = attachmentService.upload(file, null, userId, BusinessType.USER.getType(),
                AttachConst.AVATAR);
        return new AttachmentDto(attachment.getId(), attachment.getFileName(), attachment.getPath());
    }

    @ApiOperation("用户修改头像")
    @PostMapping("/updateAvatar")
    public void updateAvatar(@RequestBody UserUpdateVo updateVo) {
        User user = new User();
        BeanUtil.copyProperties(updateVo, user);
        userService.updateAvatar(user);
    }

    @ApiOperation(value = "当前用户上传签名")
    @PostMapping("/sign/upload")
    public AttachmentDto uploadSign(@RequestParam("file") MultipartFile file) {
        String userId = userSupport.getUserId();
        Attachment attachment = attachmentService.upload(file, null, userId, BusinessType.USER.getType(),
                AttachConst.SIGN);
        return new AttachmentDto(attachment.getId(), attachment.getFileName(), attachment.getPath());
    }

    @ApiOperation(value = "查看密码")
    @GetMapping("/view/password")
    public Map<String, String> viewPassword(){
        Map<String, String> map = userService.viewPassword();
        return map;
    }

    // pc端修改密码
    @ApiOperation(value = "用户修改密码")
    @PostMapping("/passwordUpdate")
    public void passwordUpdate(@RequestBody @Valid UserPasswordUpdateVo updateVo) {
        userService.modifyPassword(null, updateVo.getPassword(), updateVo.getConfirmPassword(), updateVo.getOldPassword());
    }

    // app端修改密码
    @ApiOperation(value = "用户修改密码")
    @PostMapping("/appPasswordUpdate")
    public void appPasswordUpdate(@RequestBody @Valid UserPasswordUpdateVo updateVo) {
        userService.appModifyPassword(null, updateVo.getPassword(), updateVo.getConfirmPassword(), updateVo.getOldPassword());
    }

    // 管理员修改pc端密码
    @PreAuthorize("hasAuthority('sys:user:adminPcPasswordUpdate')")
    @ApiOperation(value = "用户修改密码")
    @PostMapping("/adminPcPasswordUpdate")
    public void adminPcPasswordUpdate(@RequestBody UserPasswordUpdateVo updateVo) {
        userService.adminPcModifyPassword(updateVo.getId(), updateVo.getPassword(), updateVo.getConfirmPassword() );
    }

    // 管理员修改app端密码
    @PreAuthorize("hasAuthority('sys:user:adminAppPasswordUpdate')")
    @ApiOperation(value = "用户修改密码")
    @PostMapping("/adminAppPasswordUpdate")
    public void adminAppPasswordUpdate(@RequestBody UserPasswordUpdateVo updateVo) {
        userService.adminAppModifyPassword(updateVo.getId(), updateVo.getPassword(), updateVo.getConfirmPassword() );
    }

    @ApiOperation(value = "获取签名")
    @PostMapping("/sign")
    public AttachmentDto getSign() {
        String userId = userSupport.getUserId();
        return attachmentService.getByBiz(userId, BusinessType.USER, AttachConst.SIGN);
    }

    @PreAuthorize("hasAuthority('sys:user:onlinetranslation')")
    @ApiOperation("微信解绑")
    @PostMapping("/onlinetranslation/{id}")
    public boolean onlinetranslation(@PathVariable("id") String id) {
        boolean bool = userService.wechatOnlineTranslation( id );
        return bool;
    }

    @PreAuthorize("hasAuthority('sys:user:isopenapplogon')")
    @ApiOperation("启用和禁用APP登录")
    @PostMapping("/isOpenAppLogon/{id}")
    public void isOpenAppLogon(@PathVariable("id") String id) {
        userService.isOpenAppLogon( id );
    }

    /*
    @ApiOperation("用户管理编辑")
    @PostMapping("/edit")
    public void edit(@RequestBody @Valid UserEditReqVo reqVo) {
        User oldUser = userService.getById(reqVo.getUserId());
        userService.userEdit(oldUser, reqVo.getUsername(), reqVo.getPassword(), reqVo.getAccountRemarks());
    }*/

    @PreAuthorize("hasAuthority('sys:user:departSynchronism')")
    @ApiOperation("与钉钉同步信息 - 离职员工")
    @PostMapping("/departSynchronism")
    public void departSynchronism() throws Exception {
        userService.departSynchronism();
    }

    @ApiOperation("与企业微信 - 通讯录同步信息")
    @PostMapping("/we/com/synchronism")
    public void weComSynchronism() {
        userService.synchronismWeCom();
    }

}